/*
 * Copyright (C) 2012-2013 Matthias Zeimer and the miniframes project group.
 * All rights reserved. 
 * 
 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.opensource.org/licenses/EPL-1.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.miniframes.minivalues;

import static org.junit.Assert.assertEquals;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.util.Date;
import java.util.Locale;
import java.util.UUID;

import org.junit.Test;

/**
 * <p>
 * Test-suite of {@link SerialisationSupport}.
 * </p>
 * 
 * @author Matthias Zeimer
 * @version 1
 * @since 0.1, 18.04.2013
 */
public class SerialisationSupportTest {

    @SuppressWarnings("cast")
    @Test
    public void classNamesTest() {
        assertEquals("int", Integer.TYPE.getName());
        assertEquals("java.lang.Integer", ((Object) (int) 1).getClass()
                .getName());
        assertEquals("java.lang.Byte", ((Object) (byte) 1).getClass().getName());

        assertEquals("-2147483648", String.format((Locale) null, "%+011d",
                Integer.MIN_VALUE));
        assertEquals("+2147483647", String.format((Locale) null, "%+011d",
                Integer.MAX_VALUE));
        assertEquals("+0000000001", String.format((Locale) null, "%+011d", 1));
        assertEquals("-0000000001", String.format((Locale) null, "%+011d", -1));

        assertEquals("-9223372036854775808L", String.format((Locale) null,
                "%+020dL", Long.MIN_VALUE));
        assertEquals("+9223372036854775807L", String.format((Locale) null,
                "%+020dL", Long.MAX_VALUE));
        assertEquals("+0000000000000000001L", String.format((Locale) null,
                "%+020dL", 1));
        assertEquals("-0000000000000000001L", String.format((Locale) null,
                "%+020dL", -1));

    }

    @Test
    public void testSerialisation_SomeJavaTypes_WithEscapings() {
        UnmodifiableArray<Long> longArray = UnmodifiableArray.valueOf((long) 1,
                (long) -5);
        // Date is 28.04.2013 - 23:30:28:036
        UnmodifiableTimestamp aTimestamp = UnmodifiableTimestamp
                .valueOf(new Date(1367184628036L));

        Object[] properties = { (int) 42, (byte) -38,
                "This is a \"small\" idea", 'c', '\'',
                // BigDecimal.valueOf(101, 1),
                longArray, (short) 1, aTimestamp };

        assertEquals("[42i,-38b,\"This is a \\\"small\\\" idea\",\'c\',"
                + "'\\\''," + "{1L,-5L},1s,"
                + "de.miniframes.minivalues.UnmodifiableTimestamp"
                + "[\"2013-04-28T21:30:28.036Z\"]]", SerialisationSupport
                .serialise(properties));
    }

    @Test
    public void testSerialisation_allSupportedTypes() {
        UnmodifiableArray<Long> anArray = UnmodifiableArray.valueOf((long) 1,
                (long) -5);
        // Date is 28.04.2013 - 23:30:28:036
        UnmodifiableTimestamp aDate = UnmodifiableTimestamp.valueOf(new Date(
                1367184628036L));

        @SuppressWarnings("cast")
        Object[] properties = { //
        /*    */(byte) -38, //
                (short) 1, //
                (int) 42, //
                (long) 2, //
                (char) 'c', //
                (boolean) true, //
                (float) 1.3f, //
                (double) 2.4d, //
                ValidEnumForValues.ONE, //
                "A String", //
                BigInteger.valueOf(42000000), //
                BigDecimal.valueOf(101, 1), //
                MathContext.DECIMAL128, //
                UUID.fromString("21d800c8-5bfc-41b0-a71f-4a66ab120793"), //
                (UnmodifiableArray<Long>) anArray, //
                (UnmodifiableTimestamp) aDate }; //

        assertEquals(
        /*    */"[" //
                + "-38b" //
                + "," //
                + "1s" //
                + "," //
                + "42i" //
                + "," //
                + "2L" //
                + "," //
                + "\'c\'" //
                + "," //
                + "true" //
                + "," //
                + "1.3f" //
                + "," //
                + "2.4d" //
                + "," //
                + "de.miniframes.minivalues.SerialisationSupportTest$" //
                + "ValidEnumForValues.ONE" //
                + "," //
                + "\"A String\"" //
                + "," //
                + "42000000bi" //
                + "," //
                + "10.1bd" //
                + "," //
                + "java.math.MathContext[precision=34 roundingMode=HALF_EVEN]"//
                + "," //
                + "java.util.UUID[21d800c8-5bfc-41b0-a71f-4a66ab120793]" //
                + "," //
                + "{1L,-5L}" //
                + "," //
                + "de.miniframes.minivalues.UnmodifiableTimestamp" //
                + "[\"2013-04-28T21:30:28.036Z\"]" //
                + "]", //
                SerialisationSupport.serialise(properties));
    }

    static enum ValidEnumForValues {
        ONE, TWO
    }
}
